﻿using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using System.Linq;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Workflow;
using Microsoft.SharePoint.WorkflowActions;
using GeoCodeAdress.geoCode;

using System.ServiceModel;

namespace GeoCodeAdress
{
    public sealed partial class GCAdress : SequentialWorkflowActivity
    {

        public GCAdress()
        {
            InitializeComponent();
        }

        public Guid workflowId = default(System.Guid);
        public SPWorkflowActivationProperties workflowProperties = new SPWorkflowActivationProperties();

        private void onWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e)
        {
            #region GetAddress
            SPListItem listItem = workflowProperties.Item;
            SPFieldMultiLineText textField = (SPFieldMultiLineText)listItem.Fields.GetField("WorkAddress");
            string strAddress = string.Empty;

            //Gets Address if theres any to get...  else workflow ends
            if (listItem["WorkAddress"] != null)
            {
                var txtField = listItem["WorkAddress"];
                strAddress = txtField.ToString();

                if (listItem["WorkZip"] != null)
                {
                    txtField = listItem["WorkZip"];
                    strAddress += ", " + txtField.ToString();
                }
                //if (listItem["WorkCity"] != null && listItem["WorkZip"] != null)
                //{
                //    txtField = listItem["WorkCity"];
                //    strAddress += " " + txtField.ToString();
                //}
                //else 
                if (listItem["WorkCity"] != null)
                {
                    txtField = listItem["WorkCity"];
                    strAddress += ", " + txtField.ToString();
                }
                if (listItem["WorkCountry"] != null)
                {   
                    txtField = listItem["WorkCountry"];
                    strAddress += ", " + txtField.ToString();   
                }
            }
            else
            {
                listItem.Update();
                WorkflowRuntime stop = new WorkflowRuntime();
                stop.StopRuntime();
            }
            #endregion

            var key = System.Configuration.ConfigurationManager.AppSettings["SMIL.BingMap.CredentialsKey"] as string;
            GeocodeRequest req = new GeocodeRequest();

            #region Credentials, Filter & Option
            req.Credentials = new geoCode.Credentials();
            req.Credentials.ApplicationId = key;
            req.Query = strAddress;

            //Filter set to High to get an accurate coord on the address.
            ConfidenceFilter[] filters = new ConfidenceFilter[1];
            filters[0] = new ConfidenceFilter();
            filters[0].MinimumConfidence = Confidence.High;

            GeocodeOptions opt = new GeocodeOptions();
            opt.Filters = filters;
            req.Options = opt;
            #endregion

            BasicHttpBinding binding = new BasicHttpBinding();
            var serviceUri = new UriBuilder("http://dev.virtualearth.net/webservices/v1/geocodeservice/GeocodeService.svc");
            GeocodeServiceClient svc = new GeocodeServiceClient(binding, new EndpointAddress(serviceUri.Uri));
            try
            {
                #region High search filter
                //High filter gives you less response but higher accuracy
                GeocodeResponse res = svc.Geocode(req);
                if (res.Results.Length > 0)
                {
                    listItem["geoRef"] = string.Format("n={0} e={1} zoom=11",
                        (decimal)res.Results[0].Locations[0].Latitude,
                        (decimal)res.Results[0].Locations[0].Longitude);
                    listItem.Update();
                }
                #endregion
                #region Med/Low search filter                
                else
                {
                    //More response but worse accuracy with medium filter
                    filters[0].MinimumConfidence = Confidence.Medium;
                    GeocodeResponse resMedium = svc.Geocode(req);

                    if (resMedium.Results.Length > 0)
                    {
                        listItem["geoRef"] = string.Format("n={0} e={1} zoom=11", 
                            (decimal)resMedium.Results[0].Locations[0].Latitude,
                            (decimal)resMedium.Results[0].Locations[0].Longitude);
                        listItem.Update();
                    }
                //    else
                //    {
                //        filters[0].MinimumConfidence = Confidence.Low;
                //        GeocodeResponse resLow = svc.Geocode(req);
                //        if (resLow.Results.Length > 0)
                //        {
                //            latitude = (decimal)resLow.Results[0].Locations[0].Latitude;
                //            longitude = (decimal)resLow.Results[0].Locations[0].Longitude;
                //            listItem["geoRef"] = string.Format("n={0} e={1} zoom=11", latitude, longitude);
                //            listItem.Update();
                //        }
                //        else
                //        {
                //            // throw an exception that geocodes could not be found for this pub
                //            throw new Exception();
                //        }
                //    }
                }
                #endregion
            }
            catch (Exception) { }
        }
    }
}
